package com.ss.summer.utlis;


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Map的一些工具类
 * @author 毛玉杰
 * @date 2019-5-20
 */
public class MapUtil {



    /**
     * 将对象属性封装加入Map
     * @param map
     * @param o
     * @return
     * @throws IllegalAccessException
     */
    public static Map objectToMap(Map<String,Object> map,Object o) throws IllegalAccessException {
        if (o ==null){
            return map;
        }
        Field[] fields = o.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            map.put(field.getName(),field.get(o));
        }
        return map;
    }

    /**
     * 将Object转成map
     * @param o
     * @return
     * @throws IllegalAccessException
     */
    public static Map objectToMap(Object o) throws IllegalAccessException {
        if (o ==null){
            return null;
        }
        HashMap<String, Object> map = new HashMap<>();
        Field[] fields = o.getClass().getDeclaredFields();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        for (Field field : fields) {
            if(field.getType().getName().equals("java.time.LocalDateTime"))
            {
                field.setAccessible(true);
                if(field.get(o)==null)
                {
                    map.put(field.getName(),"数据库无数据");
                    continue;
                }
                LocalDateTime time = (LocalDateTime) field.get(o);
                String timeStr = time.format(formatter);
                map.put(field.getName(), timeStr);
            }else {
                field.setAccessible(true);
                map.put(field.getName(),field.get(o));
            }

        }
        return map;
    }

    /**
     * 将Object转成map,且小写转成大写
     * @param o
     * @return
     * @throws IllegalAccessException
     */
    public static Map objectToMapAndSmallCaseMore(Object o) throws IllegalAccessException {
        if (o ==null){
            return null;
        }
        HashMap<String, Object> map = new HashMap<>();
        Field[] fields = o.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            map.put(StringUtil.smallCaseMore(field.getName()), field.get(o));
        }
        return map;
    }

    /**
     * 将map的key首字母大写转小写
     * @param map
     * @return
     */
    public static Map keySmallCaseMore(Map<String,Object> map){
        HashMap<String, Object> result = new HashMap<>();
        map.forEach((k,v) ->
            result.put(StringUtil.moreCaseSmall(k),v)
        );
        return result;
    }

    /**
     * 将map的key首字母大写转小写
     * @param list
     * @return
     */
    public static List<Map> keySmallCaseMoreList(List<? extends Map> list){
        ArrayList<Map> result = new ArrayList<>();
        list.forEach(t -> result.add(keySmallCaseMore(t)) );
        return result;
    }


    /**
     * 多个转换
     * @param objectList
     * @return
     * @throws IllegalAccessException
     */
    public static List<Map> listToMapList(List<? extends Object> objectList) throws IllegalAccessException {
        List<Map> result = new ArrayList<>();
        for (Object o : objectList) {
            Map map = objectToMap(o);
            result.add(map);
        }
        return result;
    }

    /**
     * 多个转换
     * @param objectList
     * @return
     * @throws IllegalAccessException
     */
    public static List<Map> objectListToMapListAndSmallCaseMore(List<? extends Object> objectList) throws IllegalAccessException {
        List<Map> result = new ArrayList<>();
        for (Object o : objectList) {
            Map map = objectToMapAndSmallCaseMore(o);
            result.add(map);
        }
        return result;
    }

    /**
     * 将map转为object
     * @param map
     * @param clz  具体哪个类
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static<T> T mapToObject(Map<String,Object> map,Class<T> clz) throws IllegalAccessException, InstantiationException {
        if (map==null) {
            return null;
        }
        T t = clz.newInstance();
        Field[] declaredFields = t.getClass().getDeclaredFields();
        for(Field field:declaredFields){
            int mod = field.getModifiers();
            if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){
                continue;
            }
            field.setAccessible(true);
            if (field.getType().getName().equals("java.lang.Integer")){
                Object o = map.get(field.getName());
                if (o==null){
                    field.set(t,null);
                }else {
                    if (o.getClass().getName().equals("java.lang.Integer")){
                        field.set(t,o);
                    }
                    if (o.getClass().getName().equals("java.lang.String")){
                        field.set(t,Integer.parseInt((String) o));
                    }
                }
            }else {
                field.set(t,map.get(field.getName()));
            }
        }
        return t;
    }




    /**
     * 将map中的值为NUll的置为空字符串""
     *      NULL ----> ""
     * @param map 返回该map
     * @return
     */
    public static Map mapNullValueReplaceToNullString(Map map){
        if (map==null){
            return null;
        }
        Set<Map.Entry> set = map.entrySet();
        for (Map.Entry entry : set) {
            if (entry.getValue()==null){
                map.put(entry.getKey(),"");
            }
        }
        return map;
    }

    /**
     * 获取Map的值
     * @param map
     * @param keys
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> List<V> getMapValuesByKeys(Map<K,V> map,K[] keys){
        if (map==null || keys==null){
            throw new RuntimeException("不能传空值");
        }
        ArrayList<V> vs = new ArrayList<>(keys.length);
        for (int i = 0;i<keys.length;i++){
            vs.add(map.get(keys[i]));
        }
        return vs;
    }


}
